<template>
  <el-dialog
      class="scrollbar"
      v-model="dialogVisible"
      title="关联文章列表"
      :align-center="true"
      :destroy-on-close="true"
      width="900px"
      draggable
  >
    <div class="table-box">
      <ProTable
          ref="assocProTable"
          title="关联文章列表"
          :columns="columns"
          :pagination="false"
          :request-api="getTableList"
          row-key="article_id"
      >
        <!-- 表格 header 按钮 -->
        <template #tableHeader="scope">
          <el-button type="primary" :icon="CirclePlus" plain @click="openDialog">
            关联文章
          </el-button>
          <el-button type="danger" :icon="Delete" plain :disabled="!scope.isSelected" @click="batchDelete(scope.selectedListIds)">
            批量删除
          </el-button>
        </template>
        <!-- Expand -->
        <template #expand="scope">
          {{ scope.row }}
        </template>
        <!-- sort -->
        <template #sort="scope">
          <el-input-number
              size="small"
              :min="0"
              :model-value="scope.row.sort"
              :disabled="!authButton('/special/assoc/changeSort')"
              @change="(val: number) => changeSort(val, scope.row)"
          />
        </template>
        <!-- 表格操作 -->
        <template #operation="scope">
          <el-button type="danger" link :icon="Delete" v-auth="'/special/delete/*'" @click="delAssoc(scope.row)">删除</el-button>
        </template>
      </ProTable>
    </div>
  </el-dialog>
  <AssocDialog ref="assocDialogRef" @assoc="handleAssoc" />
</template>

<script setup lang="ts">
// dialog框状态
import {inject, ref} from "vue";
import {CirclePlus, Delete} from "@element-plus/icons-vue";
import ProTable from "@/components/ProTable/index.vue";
import {assoc} from "@/views/app/special/special.tsx";
import {
  changeAssocSortApi,
  deleteAssocListApi,
  saveAssocListApi,
  specialAssocListApi
} from "@/api/modules/special.ts";
import {ColumnProps, ProTableInstance} from "@/components/ProTable/interface";
import {useHandleData} from "@/hooks/useHandleData.ts";
import {Recordable} from "@/interface/types.ts";
import AssocDialog from "@/views/app/special/AssocDialog.vue";
import {ElMessage} from "element-plus";
import {authButton} from "@/hooks/useAuthButton.ts";

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）
const assocProTable = ref<ProTableInstance>();

interface DialogProps {
  rowData: any;
  assocList?: any[];
  getTableList?: () => Promise<any>;
}

const dialogVisible = ref(false);
const dialogProps = ref<DialogProps>({
  rowData: {},
  assocList: [],
});

const cateTree = inject<any>("cateTree", []);
const assocColumns = assoc(cateTree);
const columns = ref<ColumnProps[]>(assocColumns["columns"]);

// 接收父组件传过来的参数
const acceptParams = (params: DialogProps) => {
  dialogProps.value = params;
  dialogVisible.value = true;
}

// 如果你想在请求之前对当前请求参数做一些操作，可以自定义如下函数：params 为当前所有的请求参数（包括分页），最后返回请求列表接口
// 默认不做操作就直接在 ProTable 组件上绑定	:requestApi="getUserList"
const getTableList = (params: any) => {
  let newParams = JSON.parse(JSON.stringify(params));
  newParams.special_id = dialogProps.value.rowData.id;
  return specialAssocListApi(newParams);
};

const assocDialogRef = ref();
const openDialog = () => {
  const params = {
    rowData: { ...dialogProps.value.rowData },
    assocList: [...dialogProps.value.assocList as any[]],
    getTableList: assocProTable.value?.getTableList
  }
  assocDialogRef.value.acceptParams(params);
}

const handleAssoc = (assocInfos: any[]) => {
  const assocMap = dialogProps.value.assocList!.reduce((pre, cur) => {
    pre[cur.article_id] = cur;
    return pre;
  }, {});
  assocInfos.forEach(item => {
    const assocItem = assocMap[item.article_id];
    assocItem && (item.sort = assocItem.sort);
  });
  saveAssocListApi({special_id: dialogProps.value.rowData.id, assoc_list: assocInfos}).then(() => {
    ElMessage.success({ message: `关联文章成功！` });
    dialogProps.value.assocList = assocInfos;
    assocProTable.value?.getTableList();
    dialogProps.value.getTableList && dialogProps.value.getTableList();
  }).catch(error => {
    console.log(error);
  })
}

const changeSort = async (val: number, row: Recordable) => {
  if (!authButton("/special/assoc/change_sort")) {
    return;
  }
  await useHandleData(changeAssocSortApi, { id: row.id, sort: val }, `修改专题文章【${row.article_title}】排序值`);
  dialogProps.value.assocList = dialogProps.value.assocList?.map(item => {
    if (item.id === row.id) {
      return {...row, sort: val};
    } else {
      return item;
    }
  });
  assocProTable.value?.getTableList();
}

// 批量取消关联文章
const batchDelete = async (articleIds: number[]) => {
  await useHandleData(deleteAssocListApi, { article_ids: articleIds, special_id: dialogProps.value.rowData.id }, "取消关联所选文章");
  dialogProps.value.assocList = dialogProps.value.assocList?.filter(item => !articleIds.includes(item.article_id));
  assocProTable.value?.clearSelection();
  assocProTable.value?.getTableList();
  dialogProps.value.getTableList && await dialogProps.value.getTableList();
};

// 取消关联文章
const delAssoc = async (row: Recordable) => {
  await useHandleData(deleteAssocListApi, { id: row.id }, `取消关联文章【${row.article_title}】`);
  dialogProps.value.assocList = dialogProps.value.assocList?.filter(item => item.article_id != row.article_id);
  assocProTable.value?.getTableList();
  dialogProps.value.getTableList && await dialogProps.value.getTableList();
};

defineExpose({
  acceptParams
});
</script>

<style scoped lang="scss">

</style>
